#include "LoaderOBJ.h"
#include <iostream>
#include <fstream>

using namespace std;

namespace glow 
{

  MeshData *LoaderOBJ::load (const string &filename)
  {
    _nbV = _nbVt = _nbVn = _nbI = 0;
    _indiceObj = _finalIndex = NULL;
    _posObj = _texObj = _norObj = _pos = _tex = _nor = NULL;

    count(filename);

    unsigned int cpt = 1, d = 0;

    _posObj = new float[_nbV];
    if(_nbVt)
      {
	_texObj = new float[_nbVt];
	cpt++;
      }
    if(_nbVn)
      {
	_norObj = new float[_nbVn];
	cpt++;
      }

    d = _nbI/cpt;

    _indiceObj = new unsigned int[_nbI];
    _finalIndex = new unsigned int[d];

    _pos = new float[d*3];
    if(_nbVt) _tex = new float[d*2];
    if(_nbVn) _nor = new float[d*3];

    fill(filename);

    unsigned int index = 0;
    for(unsigned int i=0; i<_nbI;)
      {
	_finalIndex[index] = index;

	_pos[index*3] = _posObj[(_indiceObj[i]-1)*3];
	_pos[index*3+1] = _posObj[(_indiceObj[i]-1)*3+1];
	_pos[index*3+2] = _posObj[(_indiceObj[i]-1)*3+2];
	i++;
	if(_nbVt)
	  {
	    _tex[index*2] = _texObj[(_indiceObj[i]-1)*2];
	    _tex[index*2+1] = _texObj[(_indiceObj[i]-1)*2+1];
	    i++;
	  }
	if(_nbVn)
	  {
	    _nor[index*3] = _norObj[(_indiceObj[i]-1)*3];
	    _nor[index*3+1] = _norObj[(_indiceObj[i]-1)*3+1];
	    _nor[index*3+2] = _norObj[(_indiceObj[i]-1)*3+2];
	    i++;
	  }
	index++;
      }

    MeshData * Mp = new MeshData(filename);
    
    Mp->_vertices = _pos;
    Mp->_texcoords = _tex;
    Mp->_normals = _nor;
    Mp->_index = _finalIndex;

    Mp->_nb_vertices = d;
    Mp->_nb_texcoords = d;
    Mp->_nb_normals = d;
    Mp->_nb_indices = d/3;
    
    if(_posObj) delete[] _posObj;
    if(_texObj) delete[] _texObj;
    if(_norObj) delete[] _norObj;
    if(_indiceObj) delete[] _indiceObj;

    return Mp;
}

void LoaderOBJ::count(string filename)
{
  _nbV = _nbVt = _nbVn = _nbI = 0;
  ifstream file(filename.c_str(), ios::in);
  if(file)
    {
      string key;
      file >> key;
      while(!file.eof())
        {
	  if(key == "v")
	    _nbV+=3;
	  else if(key == "vt")
	    _nbVt+=2;
	  else if(key == "vn")
	    _nbVn+=3;
	  else if(key == "f")
            {
	      if(_nbV) _nbI+=3;
	      if(_nbVt) _nbI+=3;
	      if(_nbVn) _nbI+=3;
            }
	  file >> key;
        }
      file.close();
    }
  else
    cout<<"Couldn't open file."<<endl;
}

void LoaderOBJ::fill(string filename)
{
  char s;
  ifstream file(filename.c_str(), ios::in);
  if(file)
    {
      _nbV = _nbVt = _nbVn = _nbI = 0;
      string key;
      file >> key;
      while(!file.eof())
        {
	  if(key == "v")
            {
	      file >> _posObj[_nbV] >> _posObj[_nbV+1] >> _posObj[_nbV+2];
	      _nbV+=3;
            }
	  else if(key == "vt")
            {
	      file >> _texObj[_nbVt] >> _texObj[_nbVt+1];
	      _nbVt+=2;
            }
	  else if(key == "vn")
            {
	      file >> _norObj[_nbVn] >> _norObj[_nbVn+1] >> _norObj[_nbVn+2];
	      _nbVn+=3;
            }
	  else if(key == "f")
            {
	      for(int i=0; i<3; i++)
                {
		  file >> _indiceObj[_nbI];
		  _nbI++;
		  if(_tex)
                    {
		      file.get(s);
		      file >> _indiceObj[_nbI];
		      _nbI++;
                    }
		  if(_nor)
                    {
		      file.get(s);
		      if(!_tex) file.get(s);
		      file >> _indiceObj[_nbI];
		      _nbI++;
                    }
                }
            }
	  file >> key;
        }
      file.close();
    }
  else
    cout<<"Couldn't open file."<<endl;
}

}
